package com.naiterui.ehp.bs.im.network.mqtt.handler;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bs.im.network.protocl.Event;
import com.naiterui.ehp.bs.im.service.message.handler.OfflineMessageHandler;
import com.naiterui.ehp.bs.im.utils.Constants;
import com.naiterui.ehp.bs.im.utils.NameUtils;

/**
 * 客户端在线状态处理类
 */
@Service
public class ClientStatusHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientStatusHandler.class);

    /**
     * 离线消息处理
     */
    private final OfflineMessageHandler offlineMessageHandler;

    public ClientStatusHandler(OfflineMessageHandler offlineMessageHandler) {
        this.offlineMessageHandler = offlineMessageHandler;
    }

    /**
     * 消息解码
     */
    public Event decode(String message) {
        return JSON.toJavaObject(JSON.parseObject(message), Event.class);
    }

    /**
     * 更新客户端状态
     */
    public void changeState(int type, String userMark) {

        // 如果消息体中的I不是数字将终止后续操作
        if (!NameUtils.isIllegal(userMark)) {
            LOGGER.error("changeState ERROR ; illegal attribute [i] in notice message : type={},userMark={}", type, userMark);
            return;
        }

        Long userId = NameUtils.parseUserId(userMark);

        // 输出日志
        switch (type) {
            case Constants.CONNECT_ESTABLISHED: {// 上线

                // 记录日志
                LOGGER.info("user {} online!", userMark);

                // 检测到用户上线后要优先推送离线消息
                if (userMark.startsWith(Constants.PREFIX_DR) || userMark.startsWith(Constants.PREFIX_PT)) {
                    offlineMessageHandler.sendOfflineMessages(userMark, userId);
                }

                // 缓存中保存用户的在线状态
                RedisUtil.valueOps().set(Constants.CACHE_KEY + userMark, Constants.CONNECT_ESTABLISHED + "");

                // 终止
                break;
            }
            case Constants.CONNECT_DISCONNECT: {// 正常离线

                // 记录日志
                LOGGER.info("user {} offline!", userMark);

                // 缓存中保存用户的在线状态
                RedisUtil.valueOps().set(Constants.CACHE_KEY + userMark, Constants.CONNECT_DISCONNECT + "");
                // 如果是医生端

                // 终止
                break;
            }
            case Constants.CONNECT_LOGOUT: {// 登出离线

                // 记录日志
                LOGGER.info("user {} logout!", userMark);

                // 缓存中保存用户的在线状态
                RedisUtil.valueOps().set(Constants.CACHE_KEY + userMark, Constants.CONNECT_LOGOUT + "");

                // 终止
                break;
            }
            case Constants.CONNECT_SUDDENLY: {// 意外离线

                // 记录日志
                LOGGER.info("user {} suddenly offline!", userMark);

                // 缓存中保存用户的在线状态
                RedisUtil.valueOps().set(Constants.CACHE_KEY + userMark, Constants.CONNECT_SUDDENLY + "");

                // 终止
                break;
            }
            default: {
                LOGGER.error("changeState ERROR ; invalid message : type={},userMark={}", type, userMark);
            }
        }
    }

    /**
     * 是否在线
     */
    public boolean isOnline(String userMark) {

        // 从缓存中获取信息
        String value = (String) RedisUtil.valueOps().getString(Constants.CACHE_KEY + userMark);
        if (StringUtils.isEmpty(value) || !StringUtils.isNumeric(value)) {
            return false;
        }

        // 用户在线
        return Constants.CONNECT_ESTABLISHED == Integer.parseInt(value);
    }

    /**
     * 是否可以发送push
     */
    public boolean canPush(String userMark) {

        // 从缓存中获取信息
        String value = RedisUtil.valueOps().getString(Constants.CACHE_KEY + userMark);
        if (StringUtils.isEmpty(value) || !StringUtils.isNumeric(value)) {
            return false;
        }

        // 用户是否正常登陆中
        return Constants.CONNECT_LOGOUT != Integer.parseInt(value);
    }

}
